package ru.papergames.battleserver.model;

import ru.papergames.battleserver.BattleThreadPoolManager;
import ru.papergames.battleserver.model.battle.BallColor;
import ru.papergames.battleserver.model.battle.GameBallsLine;
import ru.papergames.battleserver.model.battle.map.Cell;
import ru.papergames.battleserver.model.battle.npc.NpcDataContainer;
import ru.papergames.battleserver.model.battle.npc.processors.NpcActionProcessor;
import ru.papergames.battleserver.model.battle.npc.processors.SimpleNpcActionProcessor;
import ru.papergames.battleserver.model.battle.services.DefaultNpcDataCalculatorImpl;
import ru.papergames.battleserver.model.battle.services.NpcDataCalculator;
import ru.papergames.battleserver.network.serverpackets.flashuser.*;
import ru.papergames.common.form.NpcPlayerForm;

import java.util.List;
import java.util.Set;

/**
 * @author Alexander Troshanin
 */
public class PaperGameNpcUser extends AbstractPaperGameUser<NpcPlayerForm> {

    private NpcDataContainer dataContainer;

    private NpcDataCalculator npcDataCalculator;

    public PaperGameNpcUser(NpcPlayerForm player) {
        super(player);
        npcDataCalculator = DefaultNpcDataCalculatorImpl.getInstance();
    }

    @Override
    public void sendPacket(final PaperGameServerPacket packet) {
        Runnable r;
        final PaperGameNpcUser thisNpcUser = this;
        switch (packet.getPacketIdValue()) {
            case PaperGameServerPacketTypes.BATTLE_MAP_INFO_PACKET_ID: {
                r = new Runnable() {
                    @Override
                    public void run() {
                        synchronized (thisNpcUser) {
                            BattleMapInfo battleMapInfo = (BattleMapInfo) packet;
                            thisNpcUser.dataContainer = new NpcDataContainer(battleMapInfo.getBattle().getBattleMap());
                        }
                    }
                };
            } break;
            case PaperGameServerPacketTypes.BATTLE_NEW_BALLS_THROWN_PACKET_ID: {
                dataContainer.incPacketsCountToBeProcessed();
                r = new Runnable() {
                    @Override
                    public void run() {
                        synchronized (thisNpcUser) {
                            npcDataCalculator.handleBallsThrow(thisNpcUser, ((BattleNewBallsThrown) packet).getBalls());
                            thisNpcUser.dataContainer.decPacketsCountToBeProcessed();
                        }
                    }
                };
            } break;
            case PaperGameServerPacketTypes.BATTLE_PLAYER_MOVED_BALL_PACKET_ID: {
                dataContainer.incPacketsCountToBeProcessed();
                r = new Runnable() {
                    @Override
                    public void run() {
                        synchronized (thisNpcUser) {
                            npcDataCalculator.handleBallMoved(thisNpcUser, ((BattlePlayerMovedBall)packet).getRoute());
                            thisNpcUser.dataContainer.decPacketsCountToBeProcessed();
                        }
                    }
                };
            } break;
            case PaperGameServerPacketTypes.BATTLE_REMOVE_BALLS_IN_LINES_PACKET_ID: {
                dataContainer.incPacketsCountToBeProcessed();
                r = new Runnable() {
                    @Override
                    public void run() {
                        synchronized (thisNpcUser) {
                            Set<Cell> cellsToBeFree = ((BattleRemoveBallsInLines)packet).getCellsToBeFree();
                            List<GameBallsLine> lines = ((BattleRemoveBallsInLines)packet).getLines();
                            BallColor ballsColor = ((BattleRemoveBallsInLines)packet).getBallsColor();
                            npcDataCalculator.handleBallsRemoved(thisNpcUser, cellsToBeFree, lines, ballsColor);
                            thisNpcUser.dataContainer.decPacketsCountToBeProcessed();
                        }
                    }
                };
            } break;
            default: {
                return;
            }
        }
        BattleThreadPoolManager.getInstance().executeNpcTask(r);
//        r.run();
    }

    public NpcDataContainer getDataContainer() {
        return dataContainer;
    }

    @Override
    public void disconnect(PaperGameServerPacket msg) {
    }

    @Override
    public boolean isInBattle() {
        return false;
    }

    @Override
    public void setInBattleState() {
    }

    @Override
    public void setNormalState() {
    }

    @Override
    public boolean isDetached() {
        return false;
    }

    @Override
    public boolean checkPingTimeout(long timeout) {
        return false;
    }

    @Override
    public long getPingTimeout() {
        return 0;
    }

    @Override
    public NpcActionProcessor getActionProcessor() {
        return SimpleNpcActionProcessor.getInstance();
    }
}
